#ifndef __Z_DRIVER_FLASH_MX35_H
#define __Z_DRIVER_FLASH_MX35_H

#include <zephyr/drivers/spi.h>
#include <zephyr/types.h>

typedef enum {
    FLASH_MX35_WRAP_BYTE_2112 = 0x00,
    FLASH_MX35_WRAP_BYTE_2048 = 0x01,
    FLASH_MX35_WRAP_BYTE_64 = 0x02,
    FLASH_MX35_WRAP_BYTE_16 = 0x03,
} flash_mx35_wrap_byte_t;

struct mx35_flash_parameters {
    uint32_t chip_size;
    uint32_t page_size;
    uint32_t block_size;
    uint32_t page_oob_size;
    uint8_t jedec_id[2]; /* Byte0: manufacturer ID; Byte1: Unique ID */
};

typedef int (*mx35_flash_api_read)(const struct device *dev, uint32_t addr, uint8_t *data,
                                   uint32_t len, uint8_t wrap_flag);
typedef int (*mx35_flash_api_write)(const struct device *dev, uint32_t addr, const uint8_t *data,
                                    uint32_t len, uint8_t wrap_flag);
typedef int (*mx35_flash_api_erase)(const struct device *dev, uint32_t addr);
typedef int (*mx35_flash_api_get_state)(const struct device *dev);
typedef const struct mx35_flash_parameters *(*mx35_flash_api_get_parameters)(
    const struct device *dev);

struct mx35_flash_driver_api {
    mx35_flash_api_read read;
    mx35_flash_api_write write;
    mx35_flash_api_erase erase;
    mx35_flash_api_get_state get_state;
    mx35_flash_api_get_parameters get_parameters;
};

/* flash api interfaces*/
static inline int mx35_flash_read(const struct device *dev, uint32_t addr, uint8_t *data,
                                  uint32_t len)
{
    const struct mx35_flash_driver_api *api = (const struct mx35_flash_driver_api *)dev->api;

    return api->read(dev, addr, data, len, FLASH_MX35_WRAP_BYTE_2048);
}

static inline int mx35_flash_write(const struct device *dev, uint32_t addr, uint8_t *data,
                                   uint32_t len)
{
    const struct mx35_flash_driver_api *api = (const struct mx35_flash_driver_api *)dev->api;

    return api->write(dev, addr, data, len, FLASH_MX35_WRAP_BYTE_2048);
}

static inline int mx35_flash_erase(const struct device *dev, uint32_t addr)
{
    const struct mx35_flash_driver_api *api = (const struct mx35_flash_driver_api *)dev->api;

    return api->erase(dev, addr);
}

static inline int mx35_flash_get_state(const struct device *dev)
{
    const struct mx35_flash_driver_api *api = (const struct mx35_flash_driver_api *)dev->api;

    return api->get_state(dev);
}

static inline const struct mx35_flash_parameters *
mx35_flash_get_parameters(const struct device *dev)
{
    const struct mx35_flash_driver_api *api = (const struct mx35_flash_driver_api *)dev->api;

    return api->get_parameters(dev);
}

static inline int mx35_flash_read_with_oob(const struct device *dev, uint32_t addr, uint8_t *data,
                                           uint32_t len)
{
    const struct mx35_flash_driver_api *api = (const struct mx35_flash_driver_api *)dev->api;

    return api->read(dev, addr, data, len, FLASH_MX35_WRAP_BYTE_2112);
}

#endif /* __Z_DRIVER_FLASH_MX35_H */
